package cn.liccshop.core.backstage.sysUser.service;

import cn.liccshop.core.backstage.sysRole.mapper.SysRoleMapper;
import cn.liccshop.core.backstage.sysUser.mapper.SysUserMapper;
import cn.liccshop.core.backstage.sysUserRole.mapper.SysUserRoleMapper;
import cn.liccshop.core.entity.SysRole;
import cn.liccshop.core.entity.SysSysMenu;
import cn.liccshop.core.entity.SysUser;
import cn.liccshop.core.entity.SysUserRole;
import cn.liccshop.core.utils.SysSysMenuUtils;
import cn.liccshop.sys.cache.CommonCacheUtil;
import cn.liccshop.sys.constants.Constants;
import cn.liccshop.sys.entity.ResultOfAdminLogin;
import cn.liccshop.sys.entity.UserElement;
import cn.liccshop.sys.exception.MySystemException;
import cn.liccshop.sys.utils.AESUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author LiCC
 * @since 2019-04-05
 */
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    private SysUserRoleMapper userRoleMapper;
    @Autowired
    private CommonCacheUtil commonCacheUtil;

    @Override
    public boolean saveAdminInfo(SysUser sysUser) {
        boolean iSuccess = false;
        String roleId = sysUser.getRemarks();
        sysUser.setRemarks(null);
        if (StringUtils.isBlank(sysUser.getId())){
            /**没有ID 添加用户**/
            /** 设置初始密码 **/
            sysUser.setPassword(AESUtil.encrypt(Constants.PASSWORD_OF_ADMIN)).setPhoto(Constants.PHOTO_OF_ADMIN);
            iSuccess = retBool(baseMapper.insert(sysUser));
            /** 插入角色 **/
            SysUserRole userRole = new SysUserRole().setRoleId(roleId).setUserId(sysUser.getId());
            userRoleMapper.insert(userRole);
        } else {
            /** 由于信息基本不会改变，改变就需要重置密码 **/
            sysUser.setPassword(AESUtil.encrypt(Constants.PASSWORD_OF_ADMIN));
            iSuccess = retBool(baseMapper.updateById(sysUser));
        }
        return iSuccess;
    }

    @Transactional(rollbackFor=Exception.class)
    @Override
    public boolean deleteAdminInfo(SysUser sysUser) throws MySystemException {
        boolean iSuccess = false;
        if (StringUtils.isBlank(sysUser.getId())){
            throw new MySystemException("参数有误！",Constants.INVALID_PARM);
        }
        /** 通过用户ID和角色ID删除用户角色关系表信息 **/
        userRoleMapper.delete(new QueryWrapper<>(new SysUserRole().setUserId(sysUser.getId()).setRoleId(sysUser.getRemarks())));
        /** 通过用户ID删除用户信息 **/
        iSuccess = retBool(baseMapper.deleteById(sysUser.getId()));
        return iSuccess;
    }

    @Override
    public String login(SysUser sysUser) throws MySystemException {
        String token = null;
        List<SysUser> sysUsers = list(new QueryWrapper<>(new SysUser().setLoginName(sysUser.getLoginName()).setDisabled(1)));
        if (CollectionUtils.isEmpty(sysUsers)){
            // 找不到用户
            throw new MySystemException("用户名或密码有误",Constants.SERVICE_FAIL);
        }
        if (sysUsers.size()>1){
            // 用户名不能同名，有多个就不能登录成功
            throw new MySystemException("用户名有误，请联系管理员",Constants.INVALID_PARM);
        }
        SysUser sysUserOfDB = sysUsers.get(0);
        if (!AESUtil.encrypt(sysUser.getPassword()).equals(sysUserOfDB.getPassword())){
            // 密码匹配失败
            throw new MySystemException("用户名或密码有误",Constants.SERVICE_FAIL);
        }
        // 密码匹配成功，开始后续操作
        try {
            token =generateToken(sysUserOfDB);
        } catch (Exception e){
            log.error("生成token失败",e);
            throw new MySystemException("生成token失败");
        }
        UserElement userElement = new UserElement();
        userElement.setUserId(sysUserOfDB.getId())
                .setToken(token);
        commonCacheUtil.putTokenWhenLogin(userElement);
        return token;
    }

    @Override
    public ResultOfAdminLogin getUserInfo(String id) throws MySystemException {
        List<Map<String, Object>> userInfos = baseMapper.selectLoginInfoByUserId(id);
        if (CollectionUtils.isEmpty(userInfos)){
            // 找不到用户
            throw new MySystemException("获取用户信息失败",Constants.SERVICE_FAIL);
        }
        /** 获取角色名称开始 一个用户只能有一个角色 **/
        List<Map<String, Object>> roles = new ArrayList<>();
        Map<String, Object> role = new HashMap<>();
        role.put("name", userInfos.get(0).get("roleName").toString());
        roles.add(role);
        /** 获取角色名称结束 **/
        /** 获取前端权限开始 前端访问页面权限，目前没用 如[{val:'*'}] “*”代表都通过 **/
        List<Map<String, Object>> perms = new ArrayList<>();
        Map<String, Object> perm = new HashMap<>();
        perm.put("val", "*");
        perms.add(perm);
        /** 获取角色名称结束 **/
        List<SysSysMenu> routers = SysSysMenuUtils.userInfoOfMenus(userInfos);
        ResultOfAdminLogin data = new ResultOfAdminLogin()
                .setNick(userInfos.get(0).get("nickname")==null?"-":userInfos.get(0).get("nickname").toString())
                .setName(userInfos.get(0).get("loginName")==null?"-":userInfos.get(0).get("loginName").toString())
                .setPhoto(userInfos.get(0).get("photo")==null?"-":userInfos.get(0).get("photo").toString())
                .setPhone(userInfos.get(0).get("phone")==null?"-":userInfos.get(0).get("phone").toString())
                .setIdentityCard(userInfos.get(0).get("dentityCard")==null?"-":userInfos.get(0).get("dentityCard").toString())
                .setRoles(roles)
                .setPerms(perms)
                .setRouters(routers);
        return data;
    }

    /**
     * 以“用户ID + ":" + 当前时间戳”的格式生成token
     * @param user
     * @return
     */
    private String generateToken(SysUser user) {
        String source = user.getId() + ":" + System.currentTimeMillis();
        String token = DigestUtils.md5Hex(source);
        return token;
    }
}
